import rules from './rules';
import Component from './component';
import errorMessage from './error-message';
import defaultErrorMessageTemplate from './error-message-template';
// import inject from '../../Plugins/inject'

let installed = false;
let ElFormItemComponent;
const exp = {
  install(Vue, options = {}) {
    if (installed) {
      return;
    }
    installed = true;
    ElFormItemComponent = Vue.component('ElFormItem');
    if (!ElFormItemComponent) {
      throw Error('please install element-ui first');
    }
    errorMessage.setTemplate(options.errorMessageTemplate || defaultErrorMessageTemplate);
    Component.fieldChange = options.fieldChange || 'verify';
    ElFormItemComponent.mixin(Component);
    init();
  },
  addRule(name, getter) {
    if (!installed) {
      throw Error('please install me');
    }
    const props = {};
    if (typeof name === 'string') {
      props[name] = {};
    } else {
      props[name.name] = name;
    }
    const _name = typeof name === 'string' ? name : name.name;
    const component = { props };
    // 监听prop变化，触发校验
    component.watch = {};
    component.watch[_name] = function() {
      if (this.verify !== undefined && this.prop) {
        this.validate('');
      }
    };
    ElFormItemComponent.mixin(component);
    return rules(_name, getter);
  },
  getRule(name) {
    return rules(name);
  },
  getErrorMessage(name, templateData) {
    return errorMessage.get(name, templateData);
  },
};
function init() {
  // exp.addRule({ name: 'required', type: Boolean }, verify => ({
  //     required:true,
  //     message: exp.getErrorMessage('length', length)
  // }))
  // 文本长度
  exp.addRule({ name: 'length', type: Number }, length => ({
    len: length,
    message: exp.getErrorMessage('length', length),
  }));
  // 最小文本长度
  exp.addRule({ name: 'minLength', type: Number }, minLength => ({
    min: minLength,
    message: exp.getErrorMessage('minLength', minLength),
  }));
  exp.addRule('filename', () => ({
    pattern: /^[^/\\\\:\\*\\?\\<\\>\\|\"]{1,255}$/,
    message: exp.getErrorMessage('filename'),
  }));
  // 数字类型
  exp.addRule('number', () => ({ type: 'number', message: exp.getErrorMessage('number') }));
  // gt
  exp.addRule({ name: 'gt', type: Number }, gt => [
    exp.getRule('number')(),
    {
      validator(rule, val, callback) {
        if (val <= gt) {
          callback(Error(exp.getErrorMessage('gt', gt)));
        } else {
          callback();
        }
      },
    },
  ]);
  // gte
  exp.addRule({ name: 'gte', type: Number }, gte => [
    exp.getRule('number')(),
    { type: 'number', min: gte, message: exp.getErrorMessage('gte', gte) },
  ]);
  // lt
  exp.addRule({ name: 'lt', type: Number }, lt => [
    exp.getRule('number')(),
    {
      validator(rule, val, callback) {
        if (val >= lt) {
          callback(Error(exp.getErrorMessage('lt', lt)));
        } else {
          callback();
        }
      },
    },
  ]);
  // lte
  exp.addRule({ name: 'lte', type: Number }, lte => [
    exp.getRule('number')(),
    { type: 'number', max: lte, message: exp.getErrorMessage('lte', lte) },
  ]);
  // 整数类型
  // exp.addRule('int', () => ({ type: 'integer', message: exp.getErrorMessage('int') }))
  exp.addRule('int', () => ({ pattern: /^-?[1-9]\d*$/, message: exp.getErrorMessage('int') }));
  // 小数
  exp.addRule('float', () => ({ pattern: /^-?([1-9]\d*.\d*|0.\d*[1-9]\d*)$/, message: exp.getErrorMessage('float') }));
  // 日期时间
  exp.addRule('datetime', () => ({ pattern: /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/, message: exp.getErrorMessage('datetime') }));
  // 日期
  exp.addRule('date', () => ({ pattern: /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/, message: exp.getErrorMessage('date') }));
  // 时间
  exp.addRule('time', () => ({ pattern: /^(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/, message: exp.getErrorMessage('time') }));

  // 最多小数位
  exp.addRule({ name: 'maxDecimalLength', type: Number }, maxDecimalLength => [
    exp.getRule('number')(),
    {
      validator(rule, val, callback) {
        const decimal = val.toString().split('.')[1];
        if (decimal && decimal.length > maxDecimalLength) {
          callback(Error(exp.getErrorMessage('maxDecimalLength', maxDecimalLength)));
        } else {
          callback();
        }
      },
    },
  ]);

  // 密码
  exp.addRule('password', () => ({
    pattern: /^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)])+$)^.{8,20}$/,
    message: exp.getErrorMessage('password'),
  }));
  // 手机号
  exp.addRule('phone', () => ({
    pattern: /^(?=\d{11}$)^1(?:3\d|4[57]|5[^4\D]|6[67]|7[^249\D]|8\d|9[189])\d{8}$/,
    message: exp.getErrorMessage('phone'),
  }));
  // 电话号码
  exp.addRule('tel', () => ({
    pattern: /^(\d{3,4}-?)?\d{7,9}$/,
    message: exp.getErrorMessage('tel'),
  }));
  // 邮编
  exp.addRule('zipcode', () => ({
    pattern: /^\d{6}$/,
    message: exp.getErrorMessage('zipcode'),
  }));
  // 身份证
  exp.addRule('idcard', () => ({
    pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
    message: exp.getErrorMessage('idcard'),
  }));
  // IP
  exp.addRule('ip', () => ({
    pattern: /^(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)$/,
    message: exp.getErrorMessage('ip'),
  }));
  // URL
  exp.addRule('url', () => ({
    pattern: /^(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?$/,
    message: exp.getErrorMessage('url'),
  }));
  // 字母数字
  exp.addRule('alnum', () => ({
    pattern: /^[a-zA-Z0-9]+$/,
    message: exp.getErrorMessage('alnum'),
  }));
  // 汉字
  exp.addRule('cn', () => ({
    pattern: /^[\u4e00-\u9fa5]+$/,
    message: exp.getErrorMessage('cn'),
  }));
  // 英文
  exp.addRule('en', () => ({
    pattern: /^[A-Za-z]+$/,
    message: exp.getErrorMessage('en'),
  }));
  // 由数字、26个英文字母或者下划线组成的字符串
  exp.addRule('username', () => ({
    pattern: /^\w{3,20}$/,
    message: exp.getErrorMessage('username'),
  }));
  // 由数字、26个英文字母或者下划线组成的字符串
  exp.addRule('tableName', () => ({
    pattern: /^\w{1,30}$/,
    message: exp.getErrorMessage('tableName'),
  }));
  // 邮箱
  exp.addRule('email', () => ({ type: 'email', message: exp.getErrorMessage('email') }));
  // 6位数字验证码
  exp.addRule('verifyCode', () => ({
    pattern: /^\d{6}$/,
    message: exp.getErrorMessage('verifyCode'),
  }));
  // 自定义正则
  exp.addRule({ name: 'formatReg', type: String }, formatReg => [
    {
      validator(rule, val, callback) {
        var formatRegs = formatReg.trim().replace(/^\//g, '').replace(/\/$/g, '');
        var pattern = new RegExp(formatRegs);
        var str = val;
        if (!pattern.test(str)) {
          callback(Error(exp.getErrorMessage('custom')));
        } else {
          callback();
        }
      },
    },
  ]);

  // 根据输入框的值判断是否存在于valueVerify属性中valueVerify:{isAdd:'添加/编辑',name:'编辑时的原始值',customNames:'names'}
  exp.addRule({ name: 'valueVerify', type: Object }, valueVerify => [
    {
      validator(rule, val, callback) {
        var customNames = valueVerify.customNames;
        if (valueVerify.isAdd && customNames) { // 添加
          if (customNames.indexOf(val.trim() + ',') !== -1) {
            callback(Error(exp.getErrorMessage('valueVerify')));
          } else {
            callback();
          }
        } else if (customNames) { // 编辑
          if (customNames.indexOf(val.trim() + ',') !== -1 && (val.trim() !== valueVerify.name)) {
            callback(Error(exp.getErrorMessage('valueVerify')));
          } else {
            callback();
          }
        } else {
          callback();
        }
      },
    },
  ]);
}
export default exp;
